//
//  MarksViewController.swift
//  Automobile
//
//  Created by erkebulan elzhan on 7/31/20.
//  Copyright © 2020 erkebulan elzhan. All rights reserved.
//

import UIKit
import SnapKit


// MARK: - Base

final class ModelsViewController: UIViewController, Alertable {
    
    // MARK: - UI Elements
    
    lazy private var tableView:UITableView = {
        let table = UITableView()
        table.delegate = self
        table.dataSource = self
        table.register(ModelCell.self, forCellReuseIdentifier: "modelCell")
        table.showsVerticalScrollIndicator = false
        table.backgroundColor = .white
        table.tableFooterView = UIView()
        table.separatorStyle = .none
        return table
    }()
    
    lazy var submitButton: UIButton = {
        let button = UIButton()
        button.backgroundColor = .blueColor
        button.layer.cornerRadius = 15.0
        button.setTitle("Показать результаты", for: .normal)
        button.setTitleColor(.white, for: .normal)
        button.titleLabel?.font = UIFont.systemFont(ofSize: 17, weight: .medium)
        return button
    }()
    
    private lazy var spinnerView = SpinnerView()
    
    // MARK: - Props
    
    private lazy var viewModel: CarModelsViewModel = {
        let viewModel = CarModelsViewModel()
        viewModel.delegate = self
        return viewModel
    }()
    
    // MARK: - Actions
    
    @objc func showResults (sender: UIButton) {
        if viewModel.resultDelegate == nil {
            self.goToResultsVC()
        } else {
            self.backToRoot()
        }
    }
    
    @objc private func goBack (sender: UIBarButtonItem) {
        self.navigationController?.popViewController(animated: true)
    }
    
    @objc private func closeVC (sender: UIBarButtonItem) {
        self.navigationController?.dismiss(animated: true, completion: nil)
    }
    
    // MARK: - Init
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.viewModel.loadModels()
        
        setUpUI()
        if (viewModel.isCreateCarSection) {
            self.handleSingleSelection()
        }
    }
    
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(true)
        viewModel.lastSelectedID = nil
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        setUpNavBar()
    }
}


// MARK: - Search Delegate

extension ModelsViewController: UISearchResultsUpdating {
    func updateSearchResults(for searchController: UISearchController) {
        self.viewModel.updateSearch(text: searchController.searchBar.text)
    }
}


extension ModelsViewController: ViewModelProtocol {
    
    func updateCities(cities: [City]?) {}
    
    func updateSpinner(showSpinner: Bool) {
        showSpinner ? spinnerView.startAnimating() : spinnerView.stopAnimating()
        view.isUserInteractionEnabled = !showSpinner
    }
    
    func didHappenError(error: RequestError) {
        alertError(error: error)
    }
    
    func updatePosts() {
        tableView.reloadData()
    }
}


// MARK: - Methods

extension ModelsViewController {
    
    public func setProps (carData: CarData? = nil, resultDelegate: ResultsVCDelegate? = nil) {
        if let _carData = carData {
            viewModel.carData = _carData
        }
        
        if let delegate = resultDelegate {
            viewModel.resultDelegate = delegate
        }
    }
    
    fileprivate func back2times () {
        for _ in 0...1 {
            self.navigationController?.popViewController(animated: true)
        }
    }
    
    fileprivate func goToResultsVC () {
        let resultVC = ResultsViewController()
        viewModel.carData.models = self.viewModel.getModelsData()
        resultVC.putMarkData(carData: viewModel.carData)
        self.navigationController?.pushViewController(resultVC, animated: true)
    }
    
    fileprivate func backToRoot () {
        let marka = viewModel.carData.marka
        let models = viewModel.getModelsData()
        let mode = viewModel.carData.mode
        
        viewModel.resultDelegate!.goBack(data: CarFilter(marka: marka, models: models), type: mode)
        
        let i = navigationController?.viewControllers.firstIndex(of: self)
        let previousViewController = navigationController?.viewControllers[i!-1]
        
        if previousViewController is MarksViewController {
            self.back2times()
        } else {
            self.navigationController?.popViewController(animated: true)
        }
    }
}



// MARK: - Table View Configuration

extension ModelsViewController: UITableViewDelegate, UITableViewDataSource {
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        if (viewModel.isCreateCarSection) {
            self.openGenerations(indexPath: indexPath)
        } else {
            viewModel.updateCheckBoxes(indexPath: indexPath)
        }
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "modelCell") as! ModelCell
        cell.model = viewModel.filteredData[indexPath.section].items[indexPath.row]
        cell.selectionStyle = .none
        cell.backgroundColor = .white
        
        if (viewModel.isCreateCarSection) {
            cell.handleSingleSelection(markIcon: viewModel.carData.markaImg)
        }
        return cell
    }
    
    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        self.getTableViewHeader(for: section)
    }
    
    func numberOfSections(in tableView: UITableView) -> Int {
        return viewModel.filteredData.count
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return viewModel.filteredData[section].items.count
    }
    
    func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        return viewModel.filteredData[section].name
    }
    
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return UITableView.automaticDimension
    }
    
    private func openGenerations (indexPath: IndexPath) {
        let vc = GenerationViewController()
        vc.carData = CarData(marka: viewModel.carData.marka, markaImg: viewModel.carData.markaImg, saveToGarage: viewModel.carData.saveToGarage, mode: viewModel.carData.mode)
        
        vc.models = [viewModel.filteredData[indexPath.section].items[indexPath.row].model]
        vc.resultsVC = viewModel.resultDelegate
        self.navigationController?.pushViewController(vc, animated: true)
    }
}


// MARK:- Setup UI

extension ModelsViewController {
    
    private func setUpUI () {
        view.backgroundColor = .white
        view.addSubview(tableView)
        view.addSubview(submitButton)
        view.addSubview(spinnerView)
        
        submitButton.snp.makeConstraints { (make) in
            make.leading.trailing.equalToSuperview().inset(16)
            make.bottom.equalTo(view.safeAreaLayoutGuide).offset(-16)
            make.height.equalTo(44)
        }
        tableView.snp.makeConstraints { (make) in
            make.leading.trailing.bottom.equalToSuperview().inset(16)
            make.top.equalTo(view.safeAreaLayoutGuide).offset(16)
        }
        spinnerView.snp.makeConstraints { (make) in
            make.center.equalToSuperview()
        }
        
        submitButton.addTarget(self, action: #selector(showResults(sender:)), for: .touchUpInside)
        
        if viewModel.resultDelegate != nil && viewModel.isCreateCarSection {
            self.submitButton.setTitle("Дальше", for: .normal)
        }
    }
    
    private func setUpNavBar () {
        let backIcon = UIImage(named: "cancel")
        let backButton = UIBarButtonItem(image: backIcon, style: .plain, target: self, action: #selector(goBack(sender:)))
        backButton.tintColor = .greyColor
        
        navigationController?.navigationBar.prefersLargeTitles = true
        navigationItem.title = "Модели " + (viewModel.carData.marka?.name_ru ?? "")
        navigationItem.hidesSearchBarWhenScrolling = false
        navigationItem.leftBarButtonItem = backButton
        navigationItem.hidesBackButton = true
        
        let searchController = UISearchController(searchResultsController: nil)
        searchController.searchResultsUpdater = self
        searchController.obscuresBackgroundDuringPresentation = false
        definesPresentationContext = true
        self.navigationController?.navigationItem.largeTitleDisplayMode = .always
        searchController.searchBar.placeholder = "Поиск модели"
        self.navigationItem.searchController = searchController
    }
    
    private func getTableViewHeader (for section: Int) -> UIView {
        let view = UIView.init(frame: CGRect(x: 0, y: 0, width: tableView.frame.width, height: 32))
        view.backgroundColor = .white
        
        let titleLbl = UILabel()
        titleLbl.frame = view.frame
        titleLbl.font = UIFont.systemFont(ofSize: 18, weight: .bold)
        titleLbl.textColor = UIColor(red: 31/255, green: 45/255, blue: 61/255, alpha: 1)
        titleLbl.text = viewModel.filteredData[section].name
        view.addSubview(titleLbl)
        
        return view
    }
    
    // MARK: - Car Select Mode
    
    private func handleSingleSelection () {
        self.submitButton.isHidden = true
        self.tableView.separatorStyle = .singleLine
        self.addCloseIcon()
    }
    
    private func addCloseIcon () {
        let closeBarBnt = UIBarButtonItem(image: UIImage(named: "dismiss"), style: .plain, target: self, action: #selector(closeVC))
        closeBarBnt.tintColor = .greyColor
        self.navigationItem.rightBarButtonItem = closeBarBnt
    }
}
